Fernsteuern von GEM-Applikationen mit GEMScript 09.11.1997 (Release 1.0) von Thomas Much, Holger Weets, Manfred Lippert Inhaltsverzeichnis ================== 1 Einleitung 2 Das Konzept im šberblick 3 GEM-Nachrichten 3.1 Initialisierung 3.1.1 GS_REQUEST 3.1.2 GS_REPLY 3.1.3 Die GS_INFO-Struktur 3.2 Abmeldung 3.2.1 GS_QUIT 3.3 Fernsteuerung 3.3.1 GS_COMMAND 3.3.2 GS_ACK 3.4 Makros 3.4.1 GS_OPENMACRO 3.4.2 GS_MACRO 3.4.3 GS_WRITE 3.4.4 GS_CLOSEMACRO 4 Nachstarten eines GS-Interpreters 5 Standard-GS-Kommandos 5.1 Close 5.2 Copy 5.3 Cut 5.4 Delete 5.5 GetFront 5.6 New 5.7 Open 5.8 Paste 5.9 Print 5.10 Quit 5.11 Save 5.12 SaveAs 5.13 SelectAll 5.14 ToFront 5.15 Undo 6 Weitere GS-Kommandos 6.1 Exec 6.2 CheckApp 7 Parameter 7.1 Leere Parameter 7.2 Datei 7.3 Datei+Pfad 7.4 Script Anhang ====== A History B Kontakt 1 Einleitung ************* GEMScript ist ein Protokoll, um GEM-Applikationen fernzusteuern. Das Protokoll selbst ist sehr einfach gehalten, so daž es fr Programmierer kein grožes Problem darstellt, GEMScript in ihren Programmen zu untersttzen. Diese Dokumentation definiert dieses GEMScript-Protokoll und ist somit in erster Linie an Programmierer gerichtet. Wohlgemerkt handelt es sich bei GEMScript noch nicht um ein konkretes Programm, sondern nur um die Definition einer Kommunikation zwischen GEM-Programmen: Die am h„ufigsten auftretende Anwendung einer Kommunikation mittels GEMScript drfte die durch einen Script-Interpreter darstellen. Einen solchen Interpreter stellt z.B. "Scripter" von Holger Weets dar. Festgelegt durch ein Script in einer Sprache, die dieser Interpreter versteht, verschickt der Interpreter ber das definierte GEMScript- Protokoll Kommandos an GEM-Programme, die dann die gewnschten Aktionen ausfhren: Natrlich k”nnen auch GEM-Programme ohne einen Script-Interpreter untereinander per GEMScript kommunizieren. Die hohe Flexibilit„t des GEMScript-Protokolls er”ffnet sich dadurch, daž in keinster Weise die Kommandos vorgeschrieben sind, die versendet werden. Es ist nur definiert wie Kommandos verschickt werden, nicht aber welche Kommandos dies sind. Jede Applikation kann also ihre eigenen Kommandos bereitstellen, je nach dem, welche F„higkeiten sie eben hat. Ein Zeichenprogramm wird beispielsweise sicher andere Kommandos bereitstellen wollen, als ein Desktop oder eine Tabellenkalkulation. Es gibt jedoch ein paar Standard-Kommandos, die in nahezu jeder Applikation sinnvoll erscheinen, z.B. das ™ffnen eines Dokumentes. Daher beschreibt diese GEMScript-Dokumentation ebenfalls einen Satz solcher Standard-GS-Kommandos, an die sich jede GEMScript-f„hige Applikation - soweit m”glich - halten sollte. Zwingend ist dies jedoch nicht. 2 Das Konzept im šberblick *************************** Wie im Vorwort schon erw„hnt, handelt es sich bei GEMScript um eine Kommunikation zwischen GEM-Programmen, bei der Kommandos verschickt werden. Der eigentliche Austausch basiert auf normalen AES-Nachrichten. Das zugrundeliegende Prinzip der Kommunikation dabei ist eigentlich recht einfach: 1. Eine Applikation, die mit einer anderen kommunizieren m”chte, meldet sich zun„chst einmal bei dieser Applikation an ("Hallo! Hier bin ich und m”chte mich gerne mit dir per GEMScript unterhalten."). Dazu gibt es die Nachrichten GS_REQUEST und GS_REPLY. 2. Danach kann bereits die "Session" beginnen, d.h. man schickt sich munter Kommandos zu. Dazu gibt es die Nachrichten GS_COMMAND und GS_ACK. Die Applikationen unterhalten sich, und sagen gegenseitig, was zu tun ist. In den meisten F„llen l„uft das ganze recht einseitig ab, d.h. eine Applikation kommandiert, was zu tun ist (normalerweise der Script-Interpreter) und die andere Applikation fhrt es aus. Natrlich sind aber auch andere "Gespr„che" denkbar. 3. Will sich eine Applikation nicht mehr unterhalten, meldet sie sich einfach wieder ab ("Tschž dann!"). Dazu gibt es die Nachricht GS_QUIT. Fr Leute, denen das zu einfach ist, gibt es noch ein kleines Schmankerl, das man in seine GEMScript-f„higen Applikationen einbauen kann - aber nicht unbedingt muž: Die Aufnahme von Aktionen (Makros). Eine Applikation, die das untersttzt, nennt man "aufnahmef„hig". Dazu wird nun zwingend ein Script-Interpreter gebraucht, der noch dazu f„hig sein muž, Kommandos aufzuzeichnen, um sie sp„ter wieder abspielen zu k”nnen. Er muž quasi selbst„ndig Scripts erstellen, aufgrund der Informationen, die ihm eine Applikation liefert. Fhrt man ein solches entstandene Script zu einem sp„teren Zeitpunkt aus, so wiederholt die Applikation sinngem„ž genau das, was sie bei der Aufnahme gemacht hat. Hier der prinzipielle Ablauf einer Aufnahme: 1. Der Benutzer aktiviert die Aufnahme in einer Applikation. Die Applikation sucht daraufhin den GEMScript-Interpreter (startet ihn gegebenenfalls nach) und initialisiert die GEMScript- Kommunikation in gewohnter Weise mit GS_REQUEST/GS_REPLY. Meist muž der Benutzer nun noch ein File ausw„hlen, in der das aufzunehmende Script landen soll. 2. Die Applikation gibt dem Interpreter bekannt, daž sie jetzt gerne aufnehmen m”chte. Dazu existiert die Nachricht GS_OPENMACRO. Ist der Interpreter einverstanden, schickt er GS_MACRO zurck, als Zeichen, daž nun die Aufnahme beginnen kann. 3. Die Applikation sendet nun alle Aktionen, die aufgenommen werden sollen, mit der Nachricht GS_WRITE an den Interpreter. Dieser erzeugt daraus das Script. 4. Beendet der Benutzer die Aufnahme, so sagt die Applikation dies dem Interpreter mit der Nachricht GS_CLOSEMACRO. Fertig. Hat man eine Applikation erst mal GEMScript-f„hig gemacht, stellt im Grunde also auch die Aufnahmef„higkeit kein grožes Problem mehr dar. Um das ganze zu vervollst„ndigen gibt es noch eine weitere kleine Variante der Aufnahme: Die applikationsbergreifende Aufnahme. Dazu ist eine weitere spezielle Applikation n”tig, die diese Aufnahme koordiniert: Der Aufnahme-Server. Der Desktop "jinnee" funktioniert beispielsweise als ein solcher Server. Auch diese applikationsbergreifende Aufnahme sei kurz erl„utert: 1. Der Benutzer aktviert die applikationsbergreifende Aufnahme im Aufnahme-Server. Wie bei einer normalen Aufnahme, sucht dieser Server den GEMScript-Interpreter und initialisiert die GEMScript-Kommunikation mit GS_REQUEST/GS_REPLY. 2. Wie bei der normalen Aufnahme, beginnt der Server, eine Aufnahme beim Interpreter zu starten (GS_OPENMACRO). Der Interpreter antwortet mit GS_MACRO. 3. Aužerdem versucht der Aufnahme-Server GEMScript-Kontakt zu allen laufenden Applikationen aufzunehmen (GS_REQUEST/GS_REPLY). Bei Applikationen, bei denen dies geklappt hat, l”st der Server quasi "von aužen" eine Aufnahme mit der Nachricht GS_MACRO aus. Sind die Applikationen von aužen aufnahmef„hig, fangen sie jetzt an, munter ihre Kommandos per GS_WRITE an den Server zu schicken. (Fr die Applikationen ist der Server in diesem Falle der Interpreter.) 4. Der Server sammelt alle aufzunehmenden Kommandos aller laufenden Applikationen, kennzeichnet diese speziell (um sie sp„ter beim Abspielen des Scripts wieder zu erkennen), und schickt diese neuen Kommandos als "seine" aufzunehmenden Kommandos an den Interpreter weiter. Dieser zeichnet sie im Script auf. 4. Beendet der Benutzer die Aufnahme, unterbricht der Server die Aufnahme bei allen Applikationen ebenfalls wieder "von aužen". Ebenso beendet er seine eigene Aufnahme beim Interpreter. (Beides mit GS_CLOSEMACRO). Fertig. 5. Spielt man das entstandene Script ab, so findet der Interpreter nur Kommandos, die fr den Server bestimmt sind, und schickt diese dann auch an ihn. Der Server wiederum erkennt, daž es sich um Kommandos anderer Applikationen handelt, und leitet sie entsprechend einfach weiter. Hier sieht man den Vorteil, den der Server hat, wenn es sich um ein Desktop handelt (wie im Falle jinnee): L„uft eine Applikation beim Abspielen des Scripts nicht, kann er diese meist ohne grožen Aufwand einfach nachstarten, sofern die Applikation im Desktop angemeldet ist. Nach diesem šberblick der M”glichkeiten kann die konkrete Dokumentation des GEMScript-Protokolls beginnen. 3 GEM-Nachrichten ****************** 3.1 Initialisierung ==================== 3.1.1 GS_REQUEST ----------------- Um festzustellen, ob eine Applikation GEMScript untersttzt, schickt man ihr folgende Message. GS_REQUEST msg[0] 0x1350 (4944) msg[1] ap_id msg[2] 0 msg[3] + Pointer auf GS_INFO-Struktur msg[4] msg[5] 0 msg[6] 0 msg[7] beliebige ID Antwort: Wenn die Applikation GEMScript versteht, erh„lt man als Antwort GS_REPLY. Man muž jede Applikation natrlich nur einmal vor dem ersten Kommando auf GEMScript testen. 3.1.2 GS_REPLY --------------- GS_REPLY wird von einer GEMScript-f„higen Applikation als Antwort auf GS_REQUEST verschickt. GS_REPLY msg[0] 0x1351 (4945) msg[1] ap_id msg[2] 0 msg[3] + Pointer auf GS_INFO-Struktur msg[4] msg[5] 0 msg[6] 0: OK, Applikation kann GS-Kommunikation durchfhren sonst: Fehler, GS-Kommunikation derzeit nicht m”glich msg[7] ID aus GS_REQUEST Wenn eine Applikation in msg[6] einen Fehler meldet, drfen an sie keine weiteren GS-Nachrichten geschickt werden. Man kann aber zu einem sp„teren Zeitpunkt mit GS_REQUEST erneut die GEMScript-F„higkeit erfragen. Man beachte, daž eine Applikation mehrere GS_REQUEST-Nachrichten erhalten kann. Zum einen k”nnen verschiedene Applikationen eine Kommunikation beginnen, aber durch die ID kann eine Applikation sogar in mehreren "Sessions" gleichzeitig kommunizieren. Ist eine Applikation nur auf eine laufende Kommunikation gleichzeitig ausgelegt (z.B. weil der aktuelle Kommunikationspartner in einer globalen Variablen vermerkt wird), so muž darauf geachtet werden, daž alle folgenden GS_REQUEST-Nachrichten korrekt abgelehnt werden, wenn bereits eine Kommunikation l„uft. (Am besten mit einem Wert ungleich 0 in msg[6].) 3.1.3 Die GS_INFO-Struktur --------------------------- typedef struct { long len; /* L„nge der Struktur in Bytes */ int version; /* Versionsnummer des Protokolles beim Sender (z.Z. 0x0100 = 1.0) */ int msgs; /* Bitmap der untersttzten Nachrichten (GSM_xxx) */ long ext; /* benutzte Endung, etwa '.SIC' */ } GS_INFO; GSM_COMMAND = 0x0001 /* kann GS_COMMAND empfangen */ GSM_MACRO = 0x0002 /* kann GS_OPENMACRO, GS_WRITE und GS_CLOSEMACRO empfangen, GS_MACRO verschicken (Interpreter) */ GSM_WRITE = 0x0004 /* kann GS_OPENMACRO, GS_WRITE und GS_CLOSEMACRO verschicken, GS_MACRO empfangen (aufnahmef„hige Applikation) */ Anmerkungen zur GS_INFO-Struktur: ù Die Struktur muž per Mxalloc() im globalen Speicher alloziert sein. ù Die Strukur darf vom Empf„nger nicht ver„ndert werden. D.h. GS_REQUEST- und GS_REPLY-Sender mssen jeweils ihre eigene Struktur allozieren. ù Da man nicht feststellen kann, wann der Empf„nger die Struktur ausgelesen hat, sollte sie grunds„tzlich verfgbar sein. Es empfiehlt sich daher, die Struktur am Anfang des Programmes zu allozieren und erst am Ende wieder freizugeben. ù long belegt 32 Bit. Entspricht also auch size_t oder dem sizeof()-Typ in Pure-C. ù int belegt 16 Bit. ù ext ist fr den Interpreter gedacht. Andere Applikationen k”nnen hier 0 eintragen. 3.2 Abmeldung ============== 3.2.1 GS_QUIT -------------- GS_QUIT sollte an den Kommunikationspartner geschickt werden, wenn eine fernsteuernde Applikation keine GS_COMMAND-Befehle mehr verschickt oder wenn eine ferngesteuerte Applikation solche Nachrichten nicht mehr auswerten kann/m”chte (z.B. weil die Applikation terminiert). GS_QUIT msg[0] 0x1354 (4948) msg[1] ap_id msg[2] 0 msg[3] 0 msg[4] 0 msg[5] 0 msg[6] 0 msg[7] ID aus GS_REQUEST 3.3 Fernsteuerung ================== 3.3.1 GS_COMMAND ----------------- GS_COMMAND msg[0] 0x1352 (4946) msg[1] ap_id msg[2] 0 msg[3] + Pointer auf Kommandozeile, s.u. msg[4] msg[5] 0 msg[6] 0 msg[7] ID aus GS_REQUEST Die Kommandozeile enth„lt das eigentliche Kommando, gefolgt von optionalen Parametern. Kommando und Parameter sind durch ASCII #0 getrennt, am Ende der Kommandozeile steht ASCII #0#0, in C-Notation also z.B. "Kommando\0Parameter 1\0Parameter 2\0\0" Die Kommandos mssen beim Empf„nger ohne Beachtung der Grož-/ Kleinschreibung ausgewertet werden. Dabei w„re es sch”n, wenn m”glichst viele Standard-GS-Kommandos untersttzt wrden. Die Zeichenkette muž per Mxalloc() im globalen Speicher alloziert sein. Antwort: Als Antwort erh„lt man die Nachricht GS_ACK, die zum Freigeben dieses Speichers benutzt werden kann. Siehe auch: Parameter. 3.3.2 GS_ACK ------------- Folgende Nachricht wird von einer GEMScript-f„higen Applikation als Antwort auf GS_COMMAND verschickt. Die fernsteuernde Applikation kann beim Empfang dieser Nachricht z.B. den Speicher vom msg[3/4] wieder freigeben. GS_ACK msg[0] 0x1353 (4947) msg[1] ap_id msg[2] 0 msg[3] + exakt die Werte der empfangenen GS_COMMAND-Nachricht msg[4] msg[5] + Ergebnis bzw. Fehlermeldung als ASCIIZZ-Text (s.u.) oder NULL msg[6] msg[7] 0: (GSACK_OK) OK, Kommando wurde oder wird ausgefhrt 1: (GSACK_UNKNOWN) Kommando unbekannt 2: (GSACK_ERROR) Fehler (Kommando nicht ausgefhrt) Wird in msg[5/6] eine Rckgabe geliefert, liegt diese im Format wie die GS_COMMAND-Kommandozeile vor, also die einzelnen Werte durch ASCII #0 getrennt mit ASCII #0#0 am Ende des Rckgabestrings. Antwort: Wenn die auswertende Applikation in msg[5/6] ein Ergebnis der Funktion oder eine Fehlerbeschreibung liefert (also einen Wert ungleich NULL), muž die fernsteuernde Applikation folgende Antwort zurckschicken. Die auswertende Applikation kann dann ihrerseits den Ergebnisspeicher freigeben. GS_ACK msg[0] 0x1353 (4947) msg[1] ap_id msg[2] 0 msg[3] 0 msg[4] 0 msg[5] + exakt die Werte der empfangenen GS_ACK-Nachricht msg[6] msg[7] 0 Anmerkungen zum Rckgabestring: Der Rckgabewert eines Kommandos sollte immer ber msg[5]+msg[6] zurckgegeben werden, man sollte nicht msg[7] dafr "mižbrauchen". Dies gilt vor allem fr Kommandos, die wahr oder falsch zurckliefern. Sofern das Kommando korrekt ausgefhrt werden konnte, sollte man bei "wahr" einen beliebigen nicht-leeren Rckgabestring (z.B. "1") zurckliefern, bei "false" empfiehlt sich Leerstring oder Nullpointer. Dies ist z.B. fr den Interpreter "Scripter" von Holger sehr praktisch, denn dann k”nnen True/False-Kommandos bequem durch folgendes Script abgefragt werden: if (kommando(...)) { /* wahr */ } else { /* falsch */ } Wrde das Ergebnis ist msg[7] zurckgeliefert, mžte man im Beispiel "Scripter" folgendes schreiben: kommando(...) if (errno == 0) { /* wahr */ } else { /* falsch */ } 3.4 Makros =========== 3.4.1 GS_OPENMACRO ------------------- GS_OPENMACRO (App->Interpreter) msg[0] 0x1355 (4949) msg[1] ap_id msg[2] 0 msg[3] + Pointer auf Dateinamen, unter dem das Script gespeichert werden soll msg[4] msg[5] 0 msg[6] 0 msg[7] 0 Eine Applikation will vom Script-Interpreter aufgenommen werden. Als Antwort bekommt sie GS_MACRO. Der Interpreter sollte ber die Environment-Variable GEMSCRIPT gesucht und ggf. auch nachgestartet werden. Die Datei-Endung fr Scripte kann die Applikation vom Interpreter ber die GS_INFO-Struktur bei GS_REPLY erfahren. Diese Endung wird evtl. fr den Fileselector ben”tigt, den man in den meisten F„llen vor einer Aufnahme aufrufen wird. Zusammenfassung des Ablaufs einer Aufnahme: ù Interpreter suchen und ggf. nachstarten. (GEMSCRIPT-Variable) ù Beim Interpreter anmelden (GS_REQUEST) ù Interpreter anwortet mit GS_REPLY (liefert GS_INFO) ù Fileselector aufrufen (Extension aus GS_INFO vom Interpreter) ù Aufnahme mit GS_OPENMACRO starten ù Interpreter liefert GS_MACRO ù Aufnahme per GS_WRITE/GS_ACK ù Am Ende Aufnahme mit GS_CLOSEMACRO beenden 3.4.2 GS_MACRO --------------- GS_MACRO (Interpreter->App) msg[0] 0x1356 (4950) msg[1] ap_id msg[2] 0 msg[3] + exakt die Werte der empfangenen GS_OPENMACRO-Nachricht oder NULL bei Aufnahme-Aufforderung msg[4] msg[5] ID (am einfachsten das Dateihandle) zur Identifizierung des Scripts msg[6] 0: Datei ist ge”ffnet, Aufzeichnung kann beginnen; sonst: Fehler msg[7] 0 Zu beachten: GS_MACRO kann auch ohne ein vorheriges GS_OPENMACRO auftreten. msg[3/4] ist dann NULL. Dieser Fall soll quasi Aufforderung zur Aufnahme betrachtet werden, wodurch z.B. eine applikationsbergreifende Aufnahme durch einen externen Aufnahme-Server m”glich ist. Die Applikation wird also aufgefordert, ab jetzt alle Aktionen per GS_WRITE an den Aufnahme- Server (der das GS_MACRO gesendet hat) zu schicken. Will oder kann die Applikation gerade nicht aufnehmen, so muž sie ein GS_CLOSEMACRO zurcksenden. Zusammenfassung des Ablaufs einer erzwungenen Aufnahme: ù Aufnahmeserver (z.B. jinnee) meldet sich mit GS_REQUEST bei der Applikation an. Applikation antwortet mit GS_REPLY. Aufnahmeserver stellt ber GS_INFO-Struktur fest, daž Applikation GS_MACRO kann, also aufnahmef„hig ist. ù Aufnahmeserver erzwingt Aufnahme mit GS_MACRO (NULL im Dateinamen) ù Applikation antwortet entweder mit GS_CLOSEMACRO (Ablehnung) oder nimmt einfach mit GS_WRITE/GS_ACK die Aktionen auf. ù Aufnahmeserver oder Applikation beendet Aufnahme mit GS_CLOSEMACRO 3.4.3 GS_WRITE --------------- GS_WRITE (App->Interpreter) msg[0] 0x1357 (4951) msg[1] ap_id msg[2] 0 msg[3] + Pointer auf Kommandozeile (wie bei GS_COMMAND) msg[4] msg[5] ID aus GS_MACRO msg[6] 0 msg[7] 0 Der Interpreter antwortet auf diese Nachricht wie bei GS_COMMAND mit GS_ACK, ohne allerdings in msg[5/6] ein Ergebnis zurckzuliefern. Falls in diesem GS_ACK ein Fehler signalisiert wird, sollten keine weiteren GS_WRITE-Nachrichten verschickt werden. 3.4.4 GS_CLOSEMACRO -------------------- GS_CLOSEMACRO (App->Interpreter / Interpreter->App) msg[0] 0x1358 (4952) msg[1] ap_id msg[2] 0 msg[3] 0 msg[4] 0 msg[5] ID aus GS_MACRO msg[6] 0 msg[7] 0 Beendet die Aufzeichnung eines Scripts. Zu beachten: Die Aufnahme kann von beiden Seiten beendet werden. Sowohl von der aufnehmenden Applikation selbst, als auch vom Interpreter (Aufnahme-Server bei applikationsbergreifender Aufnahme). 4 Nachstarten eines GS-Interpreters ************************************ Damit Applikationen (z.B. zum Aufzeichnen von Makros) einen GS- Interpreter per appl_find() finden oder - falls ein solcher nicht l„uft - nachstarten k”nnen, kann im Environment die Variable GEMSCRIPT gesetzt werden, beispielsweise #_ENV GEMSCRIPT=D:\SCRIPTER\SCRIPTER.APP 5 Standard-GS-Kommandos ************************ 5.1 Close ========== Kommando: Close Parameter: Datei (optional) Rckgabe: keine Schliežt das der Datei entsprechende Fenster. Wenn keine Datei bergeben wurde, wird das oberste Fenster geschlossen. Das Kommando darf auch so implementiert sein, daž mehrere Datei-Parameter auf einmal bergeben werden k”nnen. 5.2 Copy ========= Kommando: Copy Parameter: Datei (optional) Rckgabe: keine Kopiert die Selektion der angegebenen Datei auf das Klemmbrett. Wenn keine Datei angegeben ist, wird die Selektion des obersten Fensters verwendet. 5.3 Cut ======== Kommando: Cut Parameter: Datei (optional) Rckgabe: keine Schneidet die Selektion der angegebenen Datei aus und schreibt sie auf das Klemmbrett. Wenn keine Datei angegeben ist, wird die Selektion des obersten Fensters verwendet. 5.4 Delete =========== Kommando: Delete Parameter: Datei (optional) Rckgabe: keine Schneidet die Selektion der angegebenen Datei aus. Wenn keine Datei angegeben ist, wird die Selektion des obersten Fensters verwendet. 5.5 GetFront ============= Kommando: GetFront Parameter: keine Rckgabe: Datei oder Datei+Pfad Falls das oberste Fenster der Applikation einen Namen besitzt, mit dem es in den GS-Kommandos identifiziert werden kann, sollte dieser als Antwort auf dieses Kommando zurckgeliefert werden. 5.6 New ======== Kommando: New Parameter: keine Rckgabe: keine Legt ein neues Dokument an. 5.7 Open ========= Kommando: Open Parameter: Datei+Pfad (optional) Rckgabe: keine ™ffnet die angegebene Datei. Wenn keine Datei bergeben wurde, sollte dem Benutzer die Dateiauswahlbox o.„. angezeigt werden. Das Kommando darf auch so implementiert sein, daž mehrere Datei-Parameter auf einmal bergeben werden k”nnen. 5.8 Paste ========== Kommando: Paste Parameter: Datei (optional) Rckgabe: keine Fgt den Inhalt des Klemmbretts in die Selektion der angebenenen Datei ein. Wenn keine Datei angegeben ist, wird die Selektion des obersten Fensters verwendet. 5.9 Print ========== Kommando: Print Parameter: Datei (optional) Rckgabe: keine Druckt die angegebene Datei aus. Wenn keine Datei angegeben ist, wird das oberste Fenster ausgedruckt. Das Kommando darf auch so implementiert sein, daž mehrere Datei-Parameter auf einmal bergeben werden k”nnen. 5.10 Quit ========== Kommando: Quit Parameter: keine Rckgabe: keine Beendet die Applikation. 5.11 Save ========== Kommando: Save Parameter: Datei (optional) Rckgabe: keine Speichert die angegebene Datei. Wenn keine Datei bergeben wurde, wird das oberste Fenster gespeichert. Das Kommando darf auch so implementiert sein, daž mehrere Datei-Parameter auf einmal bergeben werden k”nnen. 5.12 SaveAs ============ Kommando: SaveAs Parameter: Datei, Datei (optional) Rckgabe: keine Dieses Kommando hat mindestens einen, maximal zwei Parameter. Der erste bezeichnet den neuen Dateinamen, der zweite das zu speichernde Fenster. Wenn der zweite Parameter nicht angegeben ist, wird das oberste Fenster unter dem Dateinamen des ersten Parameters gespeichert. 5.13 SelectAll =============== Kommando: SelectAll Parameter: Datei (optional) Rckgabe: keine Markiert die gesamte angegebene Datei. Wenn keine Datei angegeben ist, wird das Dokument im obersten Fenster selektiert. 5.14 ToFront ============= Kommando: ToFront Parameter: Datei Rckgabe: keine Bringt das Fenster mit der angegebenen Datei nach vorne. 5.15 Undo ========== Kommando: Undo Parameter: Datei (optional) Rckgabe: keine Macht die letzte Aktion in der angegebenen Datei rckg„ngig. Wenn keine Datei angegeben ist, wird die letzte Aktion im obersten Fenster rckg„ngig gemacht. 6 Weitere GS-Kommandos *********************** Im folgenden sind alle Kommandos aufgelistet, bei denen zwar eine Standardisierung Sinn macht, die aber nicht zwingend untersttzt werden mssen, oder nur von bestimmten Programmen zu untersttzen sind. 6.1 Exec ========= Kommando: Exec Parameter: